//"""MLBERTMGR CPP smaple code"""
//__version__     = "1.7.3"
//__author__      = "MultilaneInc <support@multilaneinc.com>"
//__date__        = '2025-10-09'

#include "BertAcquisitionManagerLib.h"
#include <iomanip>      // std::setprecision
#include <iostream>
#include <sstream>
#include <fstream>

#include "unixtimer.h"



#ifndef _WIN32
#include <string.h>
#include <unistd.h>
void _sleep (double time) {
    usleep((int)(time * 1e3));
}
#endif

using namespace std;

////////////////////////////////////////////////////////////////////////////////////////////////////////
// global declarations
mlbertmgr *MLBERT;
const int NB_BER_CHANNELS = 4;
//Pre-allocate MEASBERDATA Struct
MeasurementsData MEASBERDATA[1024];
ushort RX_LOCK[NB_BER_CHANNELS] = { 0 };
double SNR[NB_BER_CHANNELS] = { 0 };
double BER[NB_BER_CHANNELS] = { 0 };
ushort BER_LOCK[NB_BER_CHANNELS] = { 0 };
ushort BER_TIME[NB_BER_CHANNELS] = { 0 };

// MultiRead monitor flags
int MULTIMONITORFLAGS = BERTMGR_MONITOR_RXLOCK + BERTMGR_MONITOR_SNR;
ushort MULTI_MONITOR[10];

//////////////////////////////////////////////////////////////////////////////////////////////////////////

bool connect() {
    
    int STATUS = 0;
    int STATUS1 = 0;
    // create instance
    MLBERT = mlbertmgr_createInstance();
    // Reserved for Multilane


    char * ADDRESS = "172.16.222.25";
    // Connects to device before initializing the instance
    STATUS1 = mlbertmgr_openConnection(MLBERT, ADDRESS);
    if (STATUS1){ cout << "open Connection failed" << endl; STATUS++;}

    // Initializes instance 
    InstanceParams T_PARAMS;

    char SAVE_CONFIG[] = "clk//";
    strncpy(T_PARAMS.saveConfig, SAVE_CONFIG, MAX_ADDR_LEN);
    strncpy(T_PARAMS.saveBathtub, "", MAX_ADDR_LEN);
    strncpy(T_PARAMS.saveEye, "", MAX_ADDR_LEN);
    T_PARAMS.saveEyeEnable = false;
    T_PARAMS.saveBathtubEnable = false;

    STATUS1 = mlbertmgr_initializeInstance(MLBERT, T_PARAMS);
    if (STATUS1){ cout << "open Initialize Instance failed" << endl; STATUS++;}

    //////////////////////////////////////////////////////////////////////////////////////////////////////
    //test flow 1: Get Board information of any BERT
    Board_Info INFO;
    INFO.Bootloader_Flag = false;
    
    bool PRINT = false;

    STATUS1 = mlbertmgr_getInfo(MLBERT, &INFO);
    if (STATUS1){ cout << "Read Info failed" << endl; STATUS++;}
    
    if(PRINT)
    {
    cout << "Board Info: " << endl;
    cout << "\tBoardID: " << INFO.boardID << endl;
    cout << "\tHWRev: " << INFO.HWRev / 256 << "." << INFO.HWRev % 256 << endl;
    cout << "\tFWRev: " << INFO.FWRev / 256 << "." << INFO.FWRev % 256 << endl;
    cout << "\tSilabRev: " << INFO.SilabRev << endl;
    cout << "\tIPAddress: " << ((INFO.ipAddress >> 24) & 0xff) << '.' << (INFO.ipAddress >> 16 & 0xff) << '.' << (INFO.ipAddress >> 8 & 0xff) << '.' << (INFO.ipAddress & 0xff) << endl;
    cout << "\tMask: " << ((INFO.Mask >> 24) & 0xff) << '.' << (INFO.Mask >> 16 & 0xff) << '.' << (INFO.Mask >> 8 & 0xff) << '.' << (INFO.Mask & 0xff) << endl;
    cout << "\tGateway: " << ((INFO.Gateway >> 24) & 0xff) << '.' << (INFO.Gateway >> 16 & 0xff) << '.' << (INFO.Gateway >> 8 & 0xff) << '.' << (INFO.Gateway & 0xff) << endl;
    cout << "\tMAC: " << hex << ((INFO.MAC >> 40) & 0xff) << '-' << ((INFO.MAC >> 32) & 0xff) << '-' << ((INFO.MAC >> 24) & 0xff) << '-' << (INFO.MAC >> 16 & 0xff) << '-' << (INFO.MAC >> 8 & 0xff) << '-' << (INFO.MAC & 0xff) << endl;
    cout << "\tSN: ";
    for (int i = 0; i < 10; i++) {
        cout << hex << (ushort) INFO.SN[i] << " ";
    }
    cout << endl;
    cout << "\tBootloader_Flag: " << boolalpha << INFO.Bootloader_Flag << endl;

    cout << "\tIsAdapterMode: " << INFO.isAdapterMode << endl;
    if (INFO.isAdapterMode == true) {
        cout << "\tadaptertype: " << ADAPTER_TYPE(INFO.adapterType) << endl;

    }
    }
  
//    // Enable/disable Multi Monitor Flags
    STATUS1 = mlbertmgr_enableMonitor(MLBERT, MULTIMONITORFLAGS);
    if (STATUS1){ cout << "oenable Monitor failed" << endl; STATUS++;}
    // Wait for Monitor Accumulation.
    //_sleep(350);

    return STATUS==0;
}

    
bool configure()
{
    
    
    int STATUS = 0;
    int STATUS1 = 0;
    //////////////////////////////////////////////////////////////////////////////////////////////////////
    //test flow 2:Configure Clock Settings
    //Edit parameters for your instance
    //Configurations are cashed in the instrument's memory. Enable APPLYCONFIG for the last call of the flow to trigger the configuration of the instrument
    bool APPLYCONFIG = false;
    // Clock Source
    BERTMGR_CLOCKSOURCE CLOCKSOURCE = BERTMGR_INTERNALCLKSRC;
    // Clock Mode        
    BERTMGR_CLOCKMODE CLOCKMODE = BERTMGR_REFCLK;
    // Monitor Divider                 
    BERTMGR_MONITORDIVIDER DIVIDER = BERTMGR_MONITOR_DIV4;
    //  CDR Divider
    BERTMGR_CDRDIVIDER CDRDIVIDER = BERTMGR_CDR_DIV64;

    // Set ClockSource               
    STATUS1 = mlbertmgr_setClockSource(MLBERT, CLOCKSOURCE, APPLYCONFIG);
    if (STATUS1){ cout << "set clock source failed" << endl; STATUS++;}

    // Set ClockMode
    STATUS1 = mlbertmgr_setClockMode(MLBERT, CLOCKMODE, APPLYCONFIG);
    if (STATUS1){ cout << "set clock mode failed" << endl; STATUS++;}

    //////////////////////////////////////////////////////////////////////////////////////////////////////
    //test flow 3: Configure LineRate, Coding and Amplitude Levels
	APPLYCONFIG = false;    // Configurations are cashed in the instrument's memory. Enable APPLYCONFIG for the last call of the flow to trigger the configuration of the instrument

    // Eye Mode
    BERTMGR_SIGMODULATION EYEMODE = BERTMGR_NRZ;
    // Taps Mode
    BERTMGR_TAPSMODE TAPSMODE = BERTMGR_3TAPS;
    //FEC Mode
    BERTMGR_FECMODE FECMODE = BERTMGR_FECDISABLED;
    BERTMGR_FECPATTERN FECPATTRN = BERTMGR_FECPATTERN_DISABLED;
    // Line Rate in Gb/s
    double LINERATE = 25.78125;
   // Creates PatternConfig initial struct
    PatternConfig TXPATTERN;
    // Tx Pattern                                       
    TXPATTERN.pattern = BERTMGR_PRBS31;
    // Tx Invert 
    TXPATTERN.invert = false;
    //user defined
    TXPATTERN.userDefined[0] = 0;
    TXPATTERN.userDefined[1] = 0;
    // Tx Repetition. Reserved for user Defined Tx Pattern
    TXPATTERN.repetition = 0;

    // Creates PatternConfig initial struct
    PatternConfig RXPATTERN;
    // Rx Pattern  
    RXPATTERN.pattern = BERTMGR_PRBS31;
    // Tx Invert
    RXPATTERN.invert = false;
    // Tx Repetition. Reserved for user Defined Tx Pattern
    RXPATTERN.repetition = 0;
    RXPATTERN.userDefined[0] = 0;
    RXPATTERN.userDefined[1] = 0;

    // Amplitude Level mV
    int AMPLITUDE = 200;

	// Set Linerate
    STATUS1 = mlbertmgr_setLinerate(MLBERT, &LINERATE, APPLYCONFIG);
    if (STATUS1){ cout << "set line rate failed" << endl; STATUS++;}

    // set EyeMode
    STATUS1 = mlbertmgr_setEyeMode(MLBERT, EYEMODE, APPLYCONFIG);
    if (STATUS1){ cout << "set eye mode failed" << endl; STATUS++;}
	
    //Trigger the configuration of all the applied settings
    APPLYCONFIG = true; 
    // Set Taps Mode
    STATUS1 = mlbertmgr_setTapsMode(MLBERT, TAPSMODE, APPLYCONFIG);
    if (STATUS1){ cout << "set taps Mode failed" << endl; STATUS++;}
    
    // Set FEC Mode.Check The table of features for compatibility
    //cout << "mlbertmgr_setFECMode status: " << mlbertmgr_setFECMode(MLBERT, FECMODE, FECPATTRN, APPLYCONFIG) << endl;

	int NBCHANNELS = 4;
	for (int channel = 0; channel < NBCHANNELS; channel++)
	{
		// Set Tx Pattern 
		STATUS1 = mlbertmgr_setTxPattern(MLBERT, channel, TXPATTERN, APPLYCONFIG);
                if (STATUS1){ cout << "set Tx Pattern failed" << endl; STATUS++;}

		// Set Rx Pattern 
		STATUS1 = mlbertmgr_setRxPattern(MLBERT, channel, RXPATTERN, APPLYCONFIG);
                if (STATUS1){ cout << "set Rx Pattern failed" << endl; STATUS++;}

		//#Set Calibrated Amplitude level. This function requires a calibrated Instrument
		//STATUS1 = mlbertmgr_setAmplitude(MLBERT, channel, AMPLITUDE, APPLYCONFIG); // Commented out for Multilane Internal Testing
                if (STATUS1){ cout << "set calibrated amplitude failed" << endl; STATUS++;}
	}

    //////////////////////////////////////////////////////////////////////////////////////////////////////
    //Test flow 4: Set advanced amplitude and equalization 
    // SKIP IF THE INSTRUMENT IS CALIBRATED
       // Advanced Amplitude
    AdvancedAmplitude ADVANCEDAMPLITUDE;
    // Main Tap Value(-1000 to + 1000)
    ADVANCEDAMPLITUDE.mainTap = 1000;
    // Post - emphasis Value(-1000 to + 1000)
    ADVANCEDAMPLITUDE.preEmphasis = 0;
    // Pre-emphasis Value (-1000 to +1000)
    ADVANCEDAMPLITUDE.postEmphasis = 0;
    // Inner Eye level(500 to 1500).Applied for PAM4
    ADVANCEDAMPLITUDE.innerLevel = 1000;
    // Outer Eye level (1500 to 2500). Applied to PAM4
    ADVANCEDAMPLITUDE.outerLevel = 2000;
    // Scaling Level Percentage (70, 80, 90, 100, 110, 120)
    ADVANCEDAMPLITUDE.scalingLevel = 100;
    // 7-Taps Mode
    for (int tap = 0; tap < 7; tap++) {
        ADVANCEDAMPLITUDE.advancedTaps[tap] = 0;
    }
    //APROX AMPLITUDE
    int APROXAMPLITUDE;

	for (int channel = 0; channel < NBCHANNELS; channel++)
	{
		//set advanced amplitude
		STATUS1 = mlbertmgr_setAdvancedAmplitude(MLBERT, channel, ADVANCEDAMPLITUDE, &APROXAMPLITUDE, APPLYCONFIG);
                if (STATUS1){ cout << "set advanced amplitude failed" << endl; STATUS++;}
		//cout << "APROX AMPLITUDE = " << dec << APROXAMPLITUDE << endl;
	}
    
        _sleep(6000); // Ensure stabilization after the BERT configuration. Will be replaced with an API call to read back the instrument status
               
        return STATUS==0;
}


bool doSNR()
{
    int STATUS = 0;
    int STATUS1 = 0;
    
    STATUS1 = mlbertmgr_multiReadMonitor(MLBERT, MULTIMONITORFLAGS, MULTI_MONITOR);
    if (STATUS1){ cout << "read snr monitor failed" << endl; STATUS++;}
    
    for (int channel = 0; channel < NB_BER_CHANNELS; channel++)
    {
    SNR[channel] = (double)MULTI_MONITOR[channel+NB_BER_CHANNELS]/10;
    //cout << "channel " << channel+1 << " SNR = " <<  SNR[channel] << endl;   
    }
      
    return STATUS==0;
}

bool checkRxLock()
{
    int STATUS = 0;
    int STATUS1 = 0;
    
        // Call Rx lock Status in a while loop
        int RETRY = 50;
        int alllocked = 0;
        while (RETRY > 0 && alllocked == 0) {
            
        alllocked = 1;
            STATUS1 = mlbertmgr_multiReadMonitor(MLBERT, MULTIMONITORFLAGS, MULTI_MONITOR);
            if (STATUS1){ cout << "read rx lock monitor failed" << endl; STATUS++;}
			// check rx lock every 100 ms
             for (int channel = 0; channel < NB_BER_CHANNELS; channel++)
             {
            RX_LOCK[channel] = MULTI_MONITOR[channel];
            if (RX_LOCK[channel] == 0) alllocked = 0; 
             }
            
            _sleep(100);
            RETRY -= 1;
        }
        
        cout << "########################################Retry = " << RETRY << endl;
        return STATUS == 0;
}

bool doBER()
{    
    int STATUS = 0;
    int STATUS1 = 0;
    //////////////////////////////////////////////////////////////////////////////////////////////////////
    //Test Flow 9: Execute fundamental BER Test

    int DATACOUNT = 0;
    

    // Enable BER Data Accumulation. Otherwise, the latest Data is captured
    bool ACCUMULATE = false;
    // BER Enbaled CHANNELS. First Channel is Enabled
    ushort BERENABLEDCH = 0xF;
    

    // Before starting the BER accumulation, it is recommended to add a settling time of 2 seconds
    // ML4054B requires 5 seconds after the configuration
    // "pymlbertmgr.getConfigStatus()" will be implemented in a future library release to check the instrument configuration status and avoid adding a sleep time in the application script

    // Start BER. This function requires Rx Lock.
    mlbertmgr_startBER(MLBERT, BERENABLEDCH, ACCUMULATE);
    // BER Counting Time
    // ML4054 BER Accumulation starts 4 seconds after enabling the BER process.
	// BER counting time
    _sleep(6000);

    //Get Available Data
    STATUS1 = mlbertmgr_getAvailableBERData(MLBERT, MEASBERDATA, DATACOUNT);
    if (STATUS1){ cout << "get BER available Data failed  " << DATACOUNT << endl; STATUS++;}
    
    bool PRINT = false;
    
    for (int channel = 0; channel < NB_BER_CHANNELS; channel++)
    {
    BER[channel] = MEASBERDATA[DATACOUNT - 1].berData.BER_Realtime[channel];
    BER_LOCK[channel] = MEASBERDATA[DATACOUNT - 1].berData.lockedChannels[channel];     
    BER_TIME[channel] = MEASBERDATA[DATACOUNT - 1].berData.Time[channel];
    }
    
    if(PRINT)
    {
    //print Out BER Data. Check MeasurementsData struct for more details
    cout << "Datacount: " << DATACOUNT << endl;
    cout << "Measured BER Data : " << endl;
    cout << "\tIs BER Enabled : " << MEASBERDATA[DATACOUNT - 1].berData.enabled << endl;
    for (int channel = 0; channel < NB_BER_CHANNELS; channel++) {
        cout << "\nchannel " << channel + 1 << endl;
        cout << "\tEnabled Channels : " << MEASBERDATA[DATACOUNT - 1].berData.enabledChannels[channel] << endl;
        cout << "\tLocked Channels : " << MEASBERDATA[DATACOUNT - 1].berData.lockedChannels[channel] << endl;
        cout << "\tBER Capture Time : " << MEASBERDATA[DATACOUNT - 1].berData.Time[channel] << endl;
        cout << "\tBit Count : " << MEASBERDATA[DATACOUNT - 1].berData.BitCount[channel] << endl;
        cout << "\tErrorCount_MSB: " << MEASBERDATA[DATACOUNT - 1].berData.ErrorCount_MSB[channel] << endl;
        cout << "\tErrorCount_LSB: " << MEASBERDATA[DATACOUNT - 1].berData.ErrorCount_LSB[channel] << endl;
        cout << "\tErrorCount : " << MEASBERDATA[DATACOUNT - 1].berData.ErrorCount[channel] << endl;
        cout << "\tAccumulatedErrorCount_MSB: " << MEASBERDATA[DATACOUNT - 1].berData.AccumulatedErrorCount_MSB[channel] << endl;
        cout << "\tBER_MSB_Interval: " << MEASBERDATA[DATACOUNT - 1].berData.BER_MSB_Interval[channel] << endl;
        cout << "\tBER_MSB_Realtime: " << MEASBERDATA[DATACOUNT - 1].berData.BER_MSB_Realtime[channel] << endl;
        cout << "\tAccumulatedErrorCount_LSB: " << MEASBERDATA[DATACOUNT - 1].berData.AccumulatedErrorCount_LSB[channel] << endl;
        cout << "\tBER_LSB_Interval: " << MEASBERDATA[DATACOUNT - 1].berData.BER_LSB_Interval[channel] << endl;
        cout << "\tBER_LSB_Realtime: " << MEASBERDATA[DATACOUNT - 1].berData.AccumulatedErrorCount_LSB[channel] << endl;
        cout << "\tAccumulatedErrorCount  : " << MEASBERDATA[DATACOUNT - 1].berData.AccumulatedErrorCount[channel] << endl;
        cout << "\tBER_Interval: " << MEASBERDATA[DATACOUNT - 1].berData.BER_Interval[channel] << endl;
        cout << "\tBER Realtime : " << MEASBERDATA[DATACOUNT - 1].berData.BER_Realtime[channel] << endl;
    }
    }
    //Stop BER 
    STATUS1 = mlbertmgr_stopBER(MLBERT);
    if (STATUS1){ cout << "stop BER failed" << endl; STATUS++;}
            
    return STATUS == 0;
}

    
bool Disconnect()
    {
    int STATUS = 0;
    int STATUS1 = 0;
//    // Disable Monitor process
    STATUS1 = mlbertmgr_enableMonitor(MLBERT, 0);
    if (STATUS1){ cout << "disable monitor failed" << endl; STATUS++;}
    // Disconnect
    STATUS1 = mlbertmgr_closeConnection(MLBERT);
    if (STATUS1){ cout << "close connection failed" << endl; STATUS++;}
    cout << "Destroy Instance " << endl;
    mlbertmgr_destroyInstance(MLBERT);

    return STATUS == 0;
}


int main()
{
    int ITER = 1;
    UnixTimer timer;
    ushort RX_LOCK_min[NB_BER_CHANNELS] = { 1000, 1000, 1000, 1000 };
    ushort RX_LOCK_max[NB_BER_CHANNELS] = { 0, 0, 0, 0 };
    double SNR_min[NB_BER_CHANNELS] = { 1000, 1000, 1000, 1000 };
    double SNR_max[NB_BER_CHANNELS] = { 0, 0, 0, 0 };
    double BER_min[NB_BER_CHANNELS] = { 1000, 1000, 1000, 1000 };
    double BER_max[NB_BER_CHANNELS] = { 0, 0, 0, 0 };
    ushort BER_LOCK_min[NB_BER_CHANNELS] = { 1000, 1000, 1000, 1000 };
    ushort BER_LOCK_max[NB_BER_CHANNELS] = { 0, 0, 0, 0 };
    double BER_TIME_min[NB_BER_CHANNELS] = { 10000, 10000, 10000, 10000 };
    double BER_TIME_max[NB_BER_CHANNELS] = { 0, 0, 0, 0 };
    
    double Timer_RxLock = 0;
    double Timer_RxLock_min = 10000;
    double Timer_RxLock_max = 0;
    for (int i = 0; i< ITER; i++)
    {
    timer.reset();
    timer.start();
    cout << "Connection Status = " << connect() << endl;
    cout << "################################## timer connection[ms]: " << timer.read()*1e3 << endl << endl;

    
    timer.reset();
    timer.start();
    cout << "Configuration Status = " << configure() << endl;
    cout << "################################## timer configuration[ms]: " << timer.read()*1e3 << endl << endl;
    
//    for (int i = 0; i< ITER; i++)
//    {
    // Check RX Lock status
    timer.reset();
    timer.start();
    cout << "RX Lock Status = " << checkRxLock() << endl;
    for (int channel = 0; channel < NB_BER_CHANNELS; channel++)
    {
        cout << "channel " << channel+1 << " RX LOCK = " <<  RX_LOCK[channel] << endl;
        if (RX_LOCK[channel] < RX_LOCK_min[channel]) RX_LOCK_min[channel] = RX_LOCK[channel];
        if (RX_LOCK[channel] > RX_LOCK_max[channel]) RX_LOCK_max[channel] = RX_LOCK[channel];
    }
    cout << "################################## timer RX Lock[ms]: " << timer.read()*1e3 << endl << endl;
    Timer_RxLock = timer.read()*1e3;
    if (Timer_RxLock < Timer_RxLock_min) Timer_RxLock_min = Timer_RxLock;
    if (Timer_RxLock > Timer_RxLock_max) Timer_RxLock_max = Timer_RxLock;
    
    
        //SNR
    timer.reset();
    timer.start();
    cout << "SNR Status = " << doSNR() << endl;
    for (int channel = 0; channel < NB_BER_CHANNELS; channel++)
    {
        if (SNR[channel] < SNR_min[channel]) SNR_min[channel] = SNR[channel];
        if (SNR[channel] > SNR_max[channel]) SNR_max[channel] = SNR[channel];
        cout << "channel " << channel+1 << " SNR = " <<  SNR[channel] << endl;
    }
    cout << "################################## timer SNR[ms]: " << timer.read()*1e3 << endl << endl; 
        
        
    // BER
    timer.reset();
    timer.start();
    cout << "BER Status = " << doBER() << endl;
    
    
    for (int channel = 0; channel < NB_BER_CHANNELS; channel++)
    {
        cout << "channel " << channel+1 << " BER LOCK = " <<  BER_LOCK[channel] << endl;
        cout << "channel " << channel+1 << " BER = " <<  BER[channel] << endl;
        cout << "channel " << channel+1 << " BER Time = " <<  BER_TIME[channel] << endl;
        
       
        if (BER[channel] < BER_min[channel]) BER_min[channel] = BER[channel];
        if (BER[channel] > BER_max[channel]) BER_max[channel] = BER[channel];
        if (BER_LOCK[channel] < BER_LOCK_min[channel]) BER_LOCK_min[channel] = BER_LOCK[channel];
        if (BER_LOCK[channel] > BER_LOCK_max[channel]) BER_LOCK_max[channel] = BER_LOCK[channel];
        if (BER_TIME[channel] < BER_TIME_min[channel]) BER_TIME_min[channel] = BER_TIME[channel];
        if (BER_TIME[channel] > BER_TIME_max[channel]) BER_TIME_max[channel] = BER_TIME[channel];
        
    }
    cout << "################################## timer BER[ms]: " << timer.read()*1e3 << endl << endl;
   
    
    //_sleep(350); // Required Time to refresh monitor
   // end for loop
    
    
    // Disconnect
    timer.reset();
    timer.start();
    cout << "Disconnect Status = " << Disconnect() << endl;
    cout << "################################## timer Disconnection[ms]: " << timer.read()*1e3 << endl << endl;
    cout << "################################################ ITER:" << i << endl;
    }
    
    for (int channel = 0; channel < NB_BER_CHANNELS; channel++)
    {
    cout << "### CHANNEL : " << channel << " ###" << endl; 
    cout << "RX LOCK Min-Max :   " << RX_LOCK_min[channel] << " - " << RX_LOCK_max[channel] << endl;
    cout << "SNR Min-Max :   " << SNR_min[channel] << " - " << SNR_max[channel] << endl;
    cout << "BER Min-Max :   " << BER_min[channel] << " - " << BER_max[channel] << endl;
    cout << "BER LOCK Min-Max :   " << BER_LOCK_min[channel] << " - " << BER_LOCK_max[channel] << endl;
    cout << "BER TIME Min-Max :   " << BER_TIME_min[channel] << " - " << BER_TIME_max[channel] << endl << endl;
    
    }
    
    cout << "Timer LOCK Min-Max :   " << Timer_RxLock_min << " - " << Timer_RxLock_max << endl;
    
    
    return 0;
}